<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- 信息 -->
    <link rel="icon" href="/favicon.ico" type="image/x-icon" />
    <title>admin-varlet</title>
    <meta name="author" content="尘跃" />

    <!-- 样式表 -->
    <link rel="stylesheet" href="/css/style-varlet.css">
    <!-- 百度统计 -->
    <script src="/js/tongji.js"></script>
    <!-- Vue3 -->
    <script src="/js/vue/vue.global.prod.js"></script>
    <!-- Vue UI LIB -->
    <script src="/js/vue/varlet.js"></script>
    <script src="/js/third/touch-emulator.js"></script>
    <!-- WX JS SDK -->
    <script src="/js/wx.js"></script>


    <style>
        #panel-main {
            box-sizing: border-box;
            padding: 1em;

            height: 80%;
            overflow-y: auto;
        }

        #panel-manage {
            box-sizing: border-box;
            padding: 1em;

            height: 80%;
            overflow-y: auto;
        }

        #panel-edit {
            box-sizing: border-box;
            padding: 1em;

            height: 80%;
            overflow-y: auto;
        }


        #panel-information {
            box-sizing: border-box;
            padding: 1em;

            height: 80%;
            overflow-y: auto;
        }
    </style>
</head>

<body>
    <div id="app"></div>

    <script src="/js/third/compressor.min.js"></script>
    <script src="/js/http.js"></script>
    <script src="/js/android.js"></script>
    <script>
        function compressImage(file) {
            // 不压缩gif
            const fileType = file.type;
            if (fileType.includes("gif")) {
                return file;
            }

            return new Promise((resolve) => {
                new Compressor(file, {
                    success(result) {
                        resolve(result);
                    }
                });
            })
        }

        function readFile2Base64(file) {
            return new Promise((resolve) => {
                const reader = new FileReader();
                reader.onload = function () {
                    resolve(reader.result);
                };
                reader.readAsDataURL(file);
            });
        };

        const lightThemeMD2 = null;
        const viewportDarkThemeMD2 = Varlet.Themes.toViewport(Varlet.Themes.dark);
        const viewportLightThemeMD3 = Varlet.Themes.toViewport(Varlet.Themes.md3Light);
        const viewportDarkThemeMD3 = Varlet.Themes.toViewport(Varlet.Themes.md3Dark);

        Varlet.StyleProvider(viewportLightThemeMD3);
        const app = Vue.createApp({
            template: `
                <!-- 标题栏 -->
                <header>
                    <var-app-bar title="admin-varlet">
                        <template #right>

                            <var-menu-select
                                v-model="theme"
                                placement="top-start"
                            >
                                <var-button
                                    color="transparent"
                                    text-color="#fff"
                                    round
                                    text
                                >
                                    <var-icon name="palette" :size="32"></var-icon>
                                </var-button>

                                <template #options>
                                    <var-menu-option label="MD2亮色" value="light_md2"/>
                                    <var-menu-option label="MD2暗色" value="dark_md2"/>
                                    <var-menu-option label="MD3亮色" value="light_md3"/>
                                    <var-menu-option label="MD3暗色" value="dark_md3"/>
                                </template>
                            </var-menu-select>

                        </template>
                    </var-app-bar>
                </header>

                <!-- 底部导航 -->
                <var-bottom-navigation
                    ref="bottomNav"
                    id="navigation"
                    v-model:active="activeNav"
                    @change="handleNavigationChange"
                    :fixed="true"
                >
                    <var-bottom-navigation-item label="首页" icon="home" />
                    <var-bottom-navigation-item label="文章管理" icon="menu" />
                    <var-bottom-navigation-item label="编辑文章" icon="xml" />
                    <var-bottom-navigation-item label="个人信息" icon="account-circle" />
                </var-bottom-navigation>


                <!-- 首页 -->
                <div
                    v-show="activeNav === 0"
                    id="panel-main"
                >
                    <!-- 该版本后台，开发陷入停滞；因为校园网，访问不了文档。 -->
                </div>


                <!-- 文章管理 -->
                <div
                    v-show="activeNav === 1"
                    id="panel-manage"
                >
                    <var-list
                        :finished="articleFinished"
                        v-model:loading="articleDataSourceLoading"
                        @load="loadArticleNextPage()"
                    >
                        <var-cell :key="article.id" v-for="article in articleDataSource">
                            <var-card
                                :title="article.title"
                                :subtitle="article.sort_name + ' ' + article.date"
                                :src="article.cover"
                            >
                                <!-- 描述 -->
                                <template #description>
                                    <div class="var-card__description">
                                        {{ article.content }}
                                    </div>
                                </template>

                                <template #extra>
                                    <var-space>
                                        <var-button @click="openURL('/pages/article.html?id=' + article.id)">
                                            查看
                                        </var-button>
                                        <var-button
                                            type="primary"
                                            @click="clickUpdateArticle(article.id)"
                                        >
                                            修改
                                        </var-button>
                                        <var-button
                                            type="danger"
                                            @click="deleteArticle(article.id)"
                                        >
                                            删除
                                        </var-button>
                                    </var-space>
                                </template>
                            </var-card>
                        </var-cell>

                    </var-list>

                </div>


                <!-- 编辑文章 -->
                <div
                    v-show="activeNav === 2"
                    id="panel-edit"
                >
                    <var-form
                        ref="articleForm"
                        :disabled="false"
                        :readonly="false"
                        scroll-to-error="start"
                        @submit="submitArticle"
                    >
                        <var-space direction="column" size="large">

                            <var-space direction="column">
                                <label>日期选择</label>
                                <var-date-picker v-model="articleFormData.date"/>
                            </var-space>

                            <var-space direction="column">
                                <label>封面</label>
                                <var-uploader
                                    maxlength="1"
                                    v-model="articleFormData.cover"
                                />
                            </var-space>

                            <var-input
                                placeholder="文章标题"
                                v-model="articleFormData.title"
                                :rules="[v => !!v || '标题不能为空']"
                            />

                            <var-select
                                ref="articleSortSelect"
                                placeholder="请选择分类"
                                :rules="[v => !!v || '必须选一个分类']"
                                v-model="articleFormData.sort_id"
                            >
                                <var-option
                                    v-for="item in articleSortDataSource"
                                    :label="item.name"
                                    :value="item.id"
                                />
                            </var-select>

                            <var-space direction="column">
                                <var-radio
                                    ref="articleSortRadio"
                                    v-model="articleFormData.has_author"
                                >
                                    转载
                                </var-radio>
                                <var-input
                                    placeholder="作者"
                                    :disabled="!articleFormData.has_author"
                                    v-model="articleFormData.author"
                                />
                                <var-input
                                    placeholder="作者主页"
                                    :disabled="!articleFormData.has_author"
                                    v-model="articleFormData.author_home_page"
                                />
                            </var-space>

                            <!-- 文章内容编辑 -->
                            <var-space direction="column">
                                <!-- 上传图片 -->
                                <var-space align="center">
                                    <span>上传图片</span>
                                    <var-uploader
                                        hide-list
                                        @after-read="uploadChooseImage"
                                    >
                                        <var-button round type="primary">
                                            <var-icon name="image" />
                                        </var-button>
                                    </var-uploader>
                                </var-space>

                                <var-input
                                    variant="outlined"
                                    placeholder="文章内容（markdown）"
                                    textarea
                                    v-model="articleFormData.content"
                                    :rules="[v => !!v || '内容不能为空']"
                                />
                            </var-space>

                            <div
                                style="text-align: center;"
                            >
                                <var-button
                                    type="primary"
                                    native-type="submit"
                                >
                                    {{ articleUpdateInformation.update ? "更新" : "发布" }}
                                </var-button>
                                <var-button
                                    v-show="articleUpdateInformation.update"
                                    native-type="reset"
                                    @click="articleUpdateInformation.update = false"
                                    style="margin-left: 1em;"
                                >
                                    取消更新
                                </var-button>
                            </div>
                        </var-space>
                    </var-form>
                </div>


                <!-- 个人信息 -->
                <var-space
                    direction="column"
                    :wrap="false"
                    v-show="activeNav === 3"
                    id="panel-information"
                >
                    <var-space
                        direction="column"
                        align="center"
                    >
                        <var-avatar
                            :src="'/avatar/' + userInformation.id"
                            :size="200"
                        />
                        <var-space direction="column" align="center">
                            <span style="font-size: 1.25em;">{{ userInformation.nickname }}</span>
                            <span>
                                注册时间：
                                <time :datetime="userInformation.register_time">
                                    {{ userInformation.register_time }}
                                </time>
                            </span>
                        </var-space>
                        <var-space>
                            <div>
                                <var-button type="primary" size="small" @click="showUpdateNickname = true">
                                    修改昵称
                                </var-button>
                                <var-dialog
                                    title="修改昵称"
                                    :confirm-button="false"
                                    :cancel-button="false"
                                    v-model:show="showUpdateNickname"
                                    style="--dialog-actions-padding: 0;"
                                >
                                    <template #default>
                                        <var-form @submit="updateUserNickname">
                                            <var-space direction="column" :wrap="false" size="large">
                                                <var-input
                                                    placeholder="请输入昵称"
                                                    :rules="[v => !!v || '昵称不能为空']"
                                                    v-model="updateFormData.nickname"
                                                />
                                                <var-space justify="flex-end">
                                                    <var-button type="primary" native-type="submit">
                                                        确定
                                                    </var-button>
                                                </var-space>
                                            </var-space>
                                        </var-form>
                                    </template>
                                </var-dialog>
                            </div>
                            <div>
                                <var-button type="primary" size="small" @click="showUpdatePassword = true">
                                    修改密码
                                </var-button>
                                <var-dialog
                                    title="修改密码"
                                    :confirm-button="false"
                                    :cancel-button="false"
                                    v-model:show="showUpdatePassword"
                                    style="--dialog-actions-padding: 0;"
                                >
                                    <template #default>
                                        <var-form @submit="updateUserPassword">
                                            <var-space direction="column" :wrap="false" size="large">
                                                <var-input
                                                    placeholder="请输入原先的密码"
                                                    :rules="[v => !!v || '密码不能为空']"
                                                    v-model="updateFormData.password"
                                                />
                                                <var-input
                                                    placeholder="请输入新密码"
                                                    :rules="[v => !!v || '密码不能为空']"
                                                    v-model="updateFormData.newPassword"
                                                />
                                                <var-space justify="flex-end">
                                                    <var-button type="primary" native-type="submit">
                                                        确定
                                                    </var-button>
                                                </var-space>
                                            </var-space>
                                        </var-form>
                                    </template>
                                </var-dialog>
                            </div>
                            <div>
                                <var-button type="primary" size="small" @click="showUpdateEmail = true">
                                    修改邮箱
                                </var-button>
                                <var-dialog
                                    title="修改密码"
                                    :confirm-button="false"
                                    :cancel-button="false"
                                    v-model:show="showUpdateEmail"
                                    style="--dialog-actions-padding: 0;"
                                >
                                    <template #default>
                                        <var-form @submit="updateUserEmail">
                                            <var-space direction="column" :wrap="false" size="large">
                                                <var-input
                                                    placeholder="请输入新邮箱"
                                                    :rules="[v => !!v || '邮箱不能为空']"
                                                    v-model="updateFormData.email"
                                                />
                                                <var-space
                                                    :wrap="false"
                                                    align="center"
                                                >
                                                    <var-input
                                                        placeholder="请输入验证码"
                                                        :rules="[v => !!v || '验证码不能为空']"
                                                        v-model="updateFormData.code"
                                                    />
                                                    <var-button
                                                        type="primary"
                                                        @click="getUpdateEmailCode"
                                                        :disabled="getEmailCodeText !== '获取验证码'"
                                                    >
                                                        {{ getEmailCodeText }}
                                                    </var-button>
                                                </var-space>
                                                <var-space justify="flex-end">
                                                    <var-button type="primary" native-type="submit">
                                                        确定
                                                    </var-button>
                                                </var-space>
                                            </var-space>
                                        </var-form>
                                    </template>
                                </var-dialog>
                            </div>
                        </var-space>
                    </var-space>

                    <var-divider description="" />
                    <var-space direction="column">
                        <var-list>
                            <var-cell>
                                目前发布了 {{ userInformation.articleCount }} 篇文章
                            </var-cell>
                        </var-list>
                    </var-space>

                    <var-divider description="最近更新的文章" />
                    <var-space direction="column">
                        <var-list>
                            <var-cell :key="item.id" v-for="item in articleDataSource.slice(0, 10)">
                                <var-link
                                    type="primary"
                                    :href="'/pages/article.html?id=' + item.id"
                                    target="_blank"
                                >
                                    {{ item.title }}
                                </var-link>
                            </var-cell>
                        </var-list>
                    </var-space>
                </var-space>
            `,

            async mounted() {
                const that = this;

                await this.verifyLogin();

                // 初始化 面板高度
                this.updatePanelHeight();
                window.addEventListener("resize", this.updatePanelHeight);

                // 使用安卓API
                if (/Android/i.test(window.navigator.userAgent)) {
                }

                // 获取用户信息
                const username = window.localStorage.getItem("username");
                const userInfoResponse = await HTTP.request({
                    method: "GET",
                    url: "/api/user/username/" + username
                });
                const userInfoResult = userInfoResponse.data;
                if (userInfoResult.type === "success")
                {
                    this.userInformation = userInfoResult.data;
                    // console.log(this.userInformation);

                    // 获取发布的文章数量
                    const articleCountResponse = await HTTP.request({
                        method: "GET",
                        url: "/api/article/count/user/username/" + username
                    });
                    const articleCountResult = articleCountResponse.data;
                    if (articleCountResult.type === "success")
                    {
                        this.userInformation.articleCount = articleCountResult.data;
                    }
                }

                // 获取文章分类信息
                const sortResult = (await HTTP.request({
                    method: "GET",
                    url: "/api/article/sort/all"
                })).data;
                this.articleSortDataSource = sortResult.data;
            },


            data() {
                return {
                    theme: "light",
                    activeNav: 0,

                    accessToken: "",

                    loadedArticlePage: 0,
                    articleDataSource: [],
                    articleDataSourceLoading: false,
                    articleFinished: false,

                    articleSortDataSource: [],
                    articleFormData: {
                        sort_id: null,
                        has_author: false,
                        author: "",
                        author_home_page: "",
                        cover: [],
                        title: "",
                        date: (function() {
                            const date = new Date();
                            return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
                        }()),
                        content: "",
                    },
                    articleUpdateInformation: {
                        update: false,
                        articleID: undefined,
                    },

                    // user information
                    userInformation: {
                        nickname: "",
                    },
                    showUpdateNickname: false,
                    showUpdatePassword: false,
                    showUpdateEmail: false,
                    getEmailCodeText: "获取验证码",
                    updateFormData: {
                        nickname: "",
                        password: "",
                        newPassword: "",
                    },
                };
            },


            watch: {
                // 每当 theme 改变时，这个函数就会执行
                theme(newTheme, _oldTheme) {
                    // console.log(newTheme);
                    if (newTheme === "light_md3") {
                        Varlet.StyleProvider(viewportLightThemeMD3);
                    } else if (newTheme === "dark_md3") {
                        Varlet.StyleProvider(viewportDarkThemeMD3);
                    } else if (newTheme === "light_md2") {
                        Varlet.StyleProvider(lightThemeMD2);
                    } else if (newTheme === "dark_md2") {
                        Varlet.StyleProvider(viewportDarkThemeMD2);
                    }
                    this.updatePanelHeight();
                },
            },

            methods: {

                showMessage(text) {
                    Varlet.Snackbar(text);
                },

                // 更新面板高度
                updatePanelHeight() {
                    const header = document.getElementsByTagName("header")[0];
                    const nav = document.getElementById("navigation");
                    const headerHeight = parseInt(window.getComputedStyle(header).height);
                    const navHeight = parseInt(window.getComputedStyle(nav).height);
                    const panelHeight = window.innerHeight - headerHeight - navHeight;
                    const panelHeightStyle = `${panelHeight}px`;
                    document.getElementById("panel-main").style.height = panelHeightStyle;
                    document.getElementById("panel-manage").style.height = panelHeightStyle;
                    document.getElementById("panel-edit").style.height = panelHeightStyle;
                    document.getElementById("panel-information").style.height = panelHeightStyle;
                },

                async handleNavigationChange() {
                    if (this.activeNav === 1 && !this.articleDataSource)
                    {
                        this.loadArticleNextPage();
                    }
                },

                openURL(url) {
                    window.open(url);
                },


                // 登录
                async verifyLogin() {
                    // 判断登录
                    this.accessToken  = window.localStorage.getItem("token");
                    const username = window.localStorage.getItem("username");
                    if (!this.accessToken || !username)
                    {
                        await Varlet.Dialog({
                            title: "提示",
                            message: "未登录",
                            confirmButton: true,
                            cancelButton: false,
                            closeOnClickOverlay: false,
                            onClosed: function() {
                                window.location.assign("./login.html");
                            }
                        });
                        return;
                    }

                    // 判断 token 是否有效
                    // axios.defaults.headers.common['token'] = this.accessToken;
                    HTTP.setHeaders({
                        token: this.accessToken
                    });
                    HTTP.request({
                        method: "GET",
                        url: "/api/user/verifyToken"
                    }).then(async response => {
                        const result = response.data;
                        if (!result.data)
                        {
                            window.localStorage.setItem("token", null);
                            window.localStorage.setItem("username", null);
                            await Varlet.Dialog({
                                title: "提示",
                                message: "认证失效！请重新登录。",
                                confirmButton: true,
                                cancelButton: false,
                                closeOnClickOverlay: false,
                                onClosed: function() {
                                    window.location.assign("./login.html");
                                }
                            });
                        }
                    });
                },

                // manage
                async loadArticleNextPage(reload = false)
                {
                    if (this.articleFinished)
                    {
                        this.articleDataSourceLoading = false;
                        return;
                    }
                    if (this.articleDataSource.length >= this.userInformation.articleCount)
                    {
                        this.articleFinished = true;
                        this.articleDataSourceLoading = false;
                        return;
                    }

                    // 重新加载
                    if (reload)
                    {
                        this.articleFinished = false;
                        this.loadedArticlePage = 0;
                        this.articleDataSource = [];
                        this.articleDataSourceLoading = true;
                    }

                    this.articleDataSourceLoading = true;
                    const username = window.localStorage.getItem("username");
                    const response = await HTTP.request({
                        method: "GET",
                        url: `/api/article/user/username/${username}/page/${++this.loadedArticlePage}`
                    })
                    const result = response.data;
                    if (result.type === "success")
                    {
                        for(article of result.data)
                        {
                            if (article.content.length > 200)
                            {
                                article.content = article.content.substring(0, 200) + "......";
                            }
                        }
                        this.articleDataSource.push(...result.data);
                    } else if (result.type === "failure") {
                        this.loadedArticlePage--;
                    }
                    this.articleDataSourceLoading = false;

                },


                async clickUpdateArticle(articleID)
                {
                    this.articleUpdateInformation = {
                        update: true,
                        articleID: articleID
                    }
                    await HTTP.request({
                        method: "GET",
                        url: `/api/article/${this.articleUpdateInformation.articleID}/markdown`,
                    }).then(response => {
                        const result = response.data;
                        if (result.type === "success")
                        {
                            const article = result.data;
                            const contentData = article.contentData;
                            // console.log(contentData);

                            this.articleFormData.sort_id = article.sort_id;
                            this.articleFormData.cover =
                                article.cover
                                ? [
                                    {
                                        cover: article.cover,
                                        url: article.cover,
                                    }
                                ]
                                : [];
                            this.articleFormData.has_author = article.author === this.userInformation.nickname ? false : true;
                            this.articleFormData.author = this.articleFormData.has_author ? article.author : "";
                            this.articleFormData.article_home_page = article.article_home_page;
                            this.articleFormData.title = article.title;
                            this.articleFormData.date = (function(){
                                const date = new Date(article.date);
                                return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
                            })();
                            this.articleFormData.content = contentData.content;
                        }
                    });

                    // 切换页面
                    this.activeNav = 2;
                },


                async deleteArticle(articleID)
                {
                    const that = this;
                    Varlet.Dialog({
                        title: "提示",
                        message: "是否删除",
                        closeOnClickOverlay: false,
                        onConfirm: async function() {
                            const response = await HTTP.request({
                                method: "DELETE",
                                url: `/api/article/${articleID}`,
                            });
                            const result  =  response.data;
                            await Varlet.Dialog({
                                title: "提示",
                                message: result.message,
                                confirmButton: true,
                                cancelButton: false,
                                closeOnClickOverlay: false,
                            });
                            if (result.type === "success") {
                                that.loadArticleNextPage(true);
                            }
                        }
                    });
                },

                // 返回图片url
                async uploadBase64Image(
                    base64Image,
                    {
                        uploadingMessage = "上传图片中",
                        successMessage = "上传成功",
                        failureMessage = "上传失败",
                    } = {}
                ) {
                    try {
                        Varlet.Snackbar(uploadingMessage);
                        const response = await HTTP.request({
                            method: "POST",
                            url: "/api/resource/upload/base64/img",
                            data: {
                                data: base64Image,
                            },
                        });
                        const result = response.data;
                        if (result.type === "success") {
                            Varlet.Snackbar(successMessage);
                            return result.data;
                        } else {
                            Varlet.Snackbar(failureMessage);
                            return;
                        }
                    } catch (e) {
                        console.error(e);
                        Varlet.Snackbar(failureMessage);
                        return;
                    }
                },

                // 返回图片url
                async uploadImage(
                    file,
                    {
                        uploadingMessage = "上传图片中",
                        successMessage = "上传成功",
                        failureMessage = "上传失败",
                    } = {}
                ) {
                    const image = await compressImage(file);
                    if (!image) {
                        Varlet.Snackbar(failureMessage);
                        return;
                    }

                    let response;
                    Varlet.Snackbar(uploadingMessage);
                    try {
                        response = await HTTP.request({
                            method: "POST",
                            url: "/api/resource/upload/img",
                            header: {
                                "token": this.accessToken,
                                "Content-Type": `multipart/form-data`,
                            },
                            data: {
                                img: image,
                            },
                        }).then();
                    } catch (e) {
                        console.error(e);
                        Varlet.Snackbar(failureMessage);
                        return;
                    }
                    if (!response) {
                        return;
                    }

                    const result = response.data;
                    if (!result)
                        return;
                    if (result.type === "success") {
                        Varlet.Snackbar(successMessage);
                        return result.data;
                    } else {
                        Varlet.Snackbar(failureMessage);
                        return;
                    }
                },

                // 上传用户选择图片
                async uploadChooseImage(varFile) {
                    const url = await this.uploadImage(varFile.file);
                    if (url) {
                        this.articleFormData.content += `![${varFile.name}](${url} "${varFile.name}")`;
                    }
                },

                // 发布文章
                async publishArticle() {
                    if (!this.articleFormData.title) {
                        Varlet.Snackbar("请输入标题");
                        return;
                    }
                    if (!this.articleFormData.sort_id) {
                        Varlet.Snackbar("请选择分类");
                        return;
                    }
                    if (!this.articleFormData.has_author) {
                        this.articleFormData.author = null;
                        this.articleFormData.author_home_page = null;
                    }

                    // 上传封面
                    let cover = null;
                    if (this.articleFormData.cover[0]) {
                        const file = this.articleFormData.cover[0].file;
                        cover = await this.uploadImage(file, { uploadingMessage: "封面上传中" });
                        if (!cover) {
                            const imgBase64 = await readFile2Base64(file);
                            cover = await this.uploadBase64Image(imgBase64, { uploadingMessage: "以 Base64 方式上传封面" });
                        }
                        if (!cover) {
                            const op = await Varlet.Dialog({
                                title: "提示",
                                message: "封面上传失败，是否继续发布",
                                confirmButton: true,
                                cancelButton: true,
                                closeOnClickOverlay: false,
                            });
                            if (op !== "confirm") {
                                return;
                            }
                        }
                    }

                    const articleDate = new Date(this.articleFormData.date);
                    const response = await HTTP.request({
                        method: "POST",
                        url: "/api/article",
                        data: {
                            sort_id: this.articleFormData.sort_id,
                            author: this.articleFormData.author,
                            author_home_page: this.articleFormData.author_home_page,
                            cover: cover,
                            title: this.articleFormData.title,
                            date: articleDate,
                            content_type: "markdown",
                            content: this.articleFormData.content,
                        }
                    });
                    const result = response.data;
                    if (result.type === "success") {
                        Varlet.Snackbar("发布成功");
                        this.articleFormData = {
                            sort_id: null,
                            author: "",
                            author_home_page: "",
                            cover: [],
                            title: "",
                            date: (function() {
                                const now = new Date();
                                return now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
                            }()),
                            content_type: "markdown",
                            content: "",
                        };
                    } else {
                        Varlet.Snackbar(result.message);
                    }
                },

                async updateArticle() {
                    if (
                        !this.articleUpdateInformation.update ||
                        !this.articleUpdateInformation.articleID
                    ) {
                        Varlet.Snackbar("错误");
                        this.articleUpdateInformation = {
                            update: false,
                            articleID: undefined,
                        };
                        return;
                    }
                    if (!this.articleFormData.title) {
                        Varlet.Snackbar("请输入标题");
                        return;
                    }
                    if (!this.articleFormData.sort_id) {
                        Varlet.Snackbar("请选择分类");
                        return;
                    }
                    if (!this.articleFormData.has_author) {
                        this.articleFormData.author = null;
                        this.articleFormData.author_home_page = null;
                    }

                    // 上传封面
                    let cover = null;
                    if (this.articleFormData.cover[0]) {
                        const file = this.articleFormData.cover[0].file;
                        cover = this.articleFormData.cover[0].cover.includes("/resource")
                        ? this.articleFormData.cover[0].cover
                        : await this.uploadImage(file, { uploadingMessage: "封面上传中" });

                        if (!cover) {
                            const imgBase64 = await readFile2Base64(file);
                            cover = await this.uploadBase64Image(imgBase64, { uploadingMessage: "以 Base64 方式上传封面" });
                        }
                        if (!cover) {
                            const op = await Varlet.Dialog({
                                title: "提示",
                                message: "封面上传失败，是否继续发布",
                                confirmButton: true,
                                cancelButton: true,
                                closeOnClickOverlay: false,
                            });
                            if (op !== "confirm") {
                                return;
                            }
                        }
                    }

                    const articleDate = new Date(this.articleFormData.date);
                    const response = await HTTP.request({
                        method: "PUT",
                        url: "/api/article",
                        data: {
                            id: this.articleUpdateInformation.articleID,
                            sort_id: this.articleFormData.sort_id,
                            author: this.articleFormData.author,
                            author_home_page: this.articleFormData.author_home_page,
                            cover: cover,
                            title: this.articleFormData.title,
                            date: articleDate,
                            content_type: "markdown",
                            content: this.articleFormData.content,
                        }
                    });
                    const result = response.data;
                    if (result.type === "success") {
                        Varlet.Snackbar("更新成功");
                        this.articleUpdateInformation = {
                            update: false,
                            articleID: undefined,
                        };
                        this.articleFormData = {
                            sort_id: null,
                            author: "",
                            author_home_page: "",
                            cover: [],
                            title: "",
                            date: (function() {
                                const now = new Date();
                                return now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
                            }()),
                            content_type: "markdown",
                            content: "",
                        };
                    } else {
                        Varlet.Snackbar(result.message);
                    }
                },

                // edit
                async submitArticle(valid) {
                    if (!valid) {
                        return;
                    }
                    // console.log(this.articleFormData);
                    if (this.articleUpdateInformation.update) {
                        this.updateArticle();
                    } else {
                        this.publishArticle();
                    }
                },

                // userInformation
                async updateUserNickname(valid) {
                    if (!valid) {
                        return;
                    }
                    if (this.userInformation.nickname === this.updateFormData.nickname) {
                        Varlet.Snackbar("昵称未改变");
                        return;
                    }

                    const result = await HTTP.request({
                        method: "PATCH",
                        url: "/api/user/nickname",
                        data: {
                            nickname: this.updateFormData.nickname,
                        }
                    }, false);
                    if (result.type === "success") {
                        this.userInformation.nickname = this.updateFormData.nickname;
                    }
                    this.updateFormData.nickname = "";
                    Varlet.Snackbar(result.message);
                    this.showUpdateNickname = false;
                },


                async updateUserPassword(valid) {
                    if (!valid) {
                        return;
                    }

                    const result = await HTTP.request({
                        method: "PATCH",
                        url: "/api/user/password",
                        data: {
                            password: this.updateFormData.password,
                            new_password: this.updateFormData.newPassword,
                        }
                    }, false);
                    this.updateFormData.password = "";
                    this.updateFormData.newPassword = "";
                    Varlet.Snackbar(result.message);
                    this.showUpdatePassword = false;
                    if (result.type === "success") {
                        this.verifyLogin();
                    }
                },

                async getUpdateEmailCode() {
                    if (!this.updateFormData.email) {
                        Varlet.Snackbar("请输入邮箱");
                        return;
                    }
                    if (!/[^@]{1,}@[^\.]{1,}\..{1,}/i.test(this.updateFormData.email)) {
                        Varlet.Snackbar("请输入正确的邮箱");
                        return;
                    }
                    const result = await HTTP.request({
                        method: "POST",
                        url: "/api/user/email/code",
                        data: {
                            email: this.updateFormData.email,
                        }
                    }, false);
                    Varlet.Snackbar(result.message);
                    if (result.type === "success") {
                        let second = 60;
                        this.getEmailCodeText = "60";
                        const id = setInterval(() => {
                            this.getEmailCodeText = --second;
                            if (second === 0) {
                                this.getEmailCodeText = "获取验证码";
                                clearInterval(id);
                            }
                        }, 1000);
                    }
                },
                async updateUserEmail(valid) {
                    if (!valid) {
                        return;
                    }

                    const result = await HTTP.request({
                        method: "PATCH",
                        url: "/api/user/email",
                        data: {
                            code: this.updateFormData.code,
                            email: this.updateFormData.email,
                        }
                    }, false);
                    Varlet.Snackbar(result.message);
                    if (result.type === "success") {
                        this.showUpdateEmail = false;
                    }
                },
            }
        })
        app.use(Varlet).mount('#app');
    </script>
</body>


</html>

